immutable data model
@kawasima氏考案の設計手法
CRUDのUをしないようにするArchitecture Pattern
そもそも更新がないように設計する
1つのデータに対して、複数の業務から変更が加わると複雑になる
参考
『WEB+DB PRESS Vol.130』 特集1
この文章、価値がありすぎるmrsekut.icon
手順化されているのが良い
/kawasima/イミュータブルデータモデル
イミュータブルデータモデル(入門編)
#WIP
課題
1つのeventを追加するときの手間が多すぎる
型を定義したり、tableを定義したり
eventに変化が入ったときにmigrationが面倒
dbという外部構造と、entityという内部構造がある時に、
内部構造を変える時に、外部構造を意識しなくてもよくすべき
railsとかみたいに(?)、migration toolがあればいい?
schemaに反映されるclassを変更した時に、migrationすればdbにも反映されるやつ
内部の、eventやstatus型を変更した時に、半自動で過去のDB内のデータを全てmigartionしてくれればいい
immutable data modelというよりEventのVersioningの話か
パフォーマンス
大量のeventをreduceする際のパフォーマンス
このアーキテクチャを採用したらだいたい同じになる部分が大きいので、そのへんを簡易にするライブラリがあると良さそうmrsekut.icon
Entityを以下の2種類に分ける
Event Entity
Resource Entity
手順
Step1. Entityの抽出
要求文書を書いて、5W1Hに下線を引く
まず要求を自然言語で書いて、entityを抽出するというのが面白い
最初からER図を書くようなことをしてはいけない
Entityの線引きの難しさがあるため、データだけ見ても良い線引ができないためmrsekut.icon
その下線部がEntityの属性の候補となる
Entityの命名は特に重要
他の概念の命名に関わるため
Entityの単一性・同一性・カテゴリの認識をチーム内で合わせる
Step2. Entityを「Resource(ヒト・モノ)」と「Event(コト)」に分類する
日時を持つかどうかで判断できる
イベントは、Entity名に「〜する」と言えば意味が通る
命名にも役立つ
Step3では「Event」について、Step4では「Resource」について考える
Step3. Event Entityは1つの日時属性しかもたないようにする
ここがかなり真髄mrsekut.icon*3
複数の日時属性を持つEntityは分割する
そうするとEvent Entityはimmutableになる
生成された後、更新されることはない
Step4. リソースに隠されたイベントを抽出する
各Resource Entityに着目し、変更日時や変更者などの属性を持つか考える
ここで、それらの属性をEvent Entityとして分離することを検討する
それらの属性があると、Resource Entityはどうしてもmutableになる
これをEvent Entityに分離することで、更新頻度を下げることができる
Step5. 非依存関係を交差Entityで表現する
非依存関係を交差Entityで表現する
https://engineering.reiwatravel.co.jp/blog/newt-point-immutable-data-model
updateがいつ起きるのかを洗い出す
データを変更するDomain Eventを洗い出す
e.g. 会員の情報を変更する
変更した時の情報をちゃんと持たせていないといけない
日時だけでは足りないことがる
例えば、beforeとafterの情報を持っていないと、ロールバックできない
e.g. ユーザーが誤って退会したので戻してほしいと言われた
https://www.slideshare.net/kawasima/ss-40471672
https://www.slideshare.net/kawasima/ss-44958468
https://engineering.reiwatravel.co.jp/blog/newt-point-immutable-data-model
https://www.ikkitang1211.site/entry/stafes2021-16
全部をEvent Sourcing的にするのには、記録や保管にお金がかかる
ので、全部に対して行うのは現実的でない
お金を生み出すもの、記録が残っていないとお金を失うリスクがあるもの、に限って実践する
悪い例
Order Entityに「注文日時」「入金日時」の両方が含まれている
以下のようなルールが必要になる
注文時には、入金日時はnullである
入金日時を入れる時に注文日時を更新してはいけない
データ型だけ見て、ルールの存在を認識できない
各ユースケースの設計書で説明を書かないといけない
変更日時と登録日時の両方を持つ必要はない
Event Entityは1つの日時属性だけ持つ
変更日時と登録日時は常に同値になるので別々に持つ意味がない
『WEB+DB PRESS Vol.130』.icon p.24